package com.lt.flashcard.view;

import java.util.ArrayList;
import java.util.List;

import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.xel.fn.StringFns;
import org.zkoss.zk.ui.util.Clients;

import com.lt.flashcard.Utility;
import com.lt.flashcard.model.entity.Message;
import com.lt.flashcard.model.entity.User;
import com.lt.flashcard.model.service.MessageService;
import com.lt.flashcard.model.service.Repository;
import com.lt.flashcard.model.service.UserService;

/**
 * Display message of user
 * @author ocsen
 *
 */
public class MessageVm {

    private List<Message> messages;
    private Message current;
    private User user;

    private String newmsg; // The new message
    private String toUser = ""; // The to user in new message
    private String replymsg = ""; // The reply message

    private long unread = 0; // Unread message

    @Init
    public void init() {
        if (!Utility.isLogin()) {
            Utility.loginOrAccessDenied(false);
            return;
        }

        setUser(Utility.getUser());
        loadMessageList();
        countUnreadMessage();
    }

    @NotifyChange({ "newmsg", "toUser" })
    @Command
    public void newmessage() {
        setNewmsg("");
        toUser = "";
    }

    @Command
    public void sendnewmessage() {
        if (Utility.isEmptyString(toUser)) {
            Clients.evalJavaScript("showNotice('', 'Bạn chưa chọn người gửi')");
            return;
        }

        if (Utility.isEmptyString(getNewmsg())) {
            Clients.evalJavaScript("showNotice('', 'Bạn chưa nhập nội dung cần gửi')");
            return;
        }

        UserService usrv = Repository.getInstance().getUserService();
        MessageService msrv = Repository.getInstance().getMessageService();
        String[] usernames = toUser.split(",");
        // TODO clean up this
        List<User> uls = usrv.findByUsername(usernames);
        User from = Utility.getUser();
        String content = StringFns.eatQuot(getNewmsg());
        for (User to : uls) {
            Message msg = msrv.sendNewMessage(from, to, content);
            messages.add(0, msg);
        }

        Clients.evalJavaScript("showNotice('', 'Tin nhắc đã được gửi thành công')");

        BindUtils.postNotifyChange(null, null, this, "messages");
    }

    @NotifyChange({ "messages", "current" })
    @Command
    public void viewmsg(@BindingParam("id") String id) {
        for (Message msg : messages) {
            if (msg.getId().toString().equals(id)) {
                MessageService srv = Repository.getInstance().getMessageService();
                current = msg;
                msg.setUnread(0);
                srv.saveMessage(msg);
                return;
            }
        }
    }

    @Command
    public void deletethread(@BindingParam("id") String id) {
        if (Utility.isEmptyString(id)) {
            return;
        }

        for (Message msg : messages) {
            if (msg.getId().toString().equals(id)) {
                current = null;
                BindUtils.postNotifyChange(null, null, this, "current");

                MessageService srv = Repository.getInstance().getMessageService();
                srv.deleteMessage(msg);
                messages.remove(msg);
                BindUtils.postNotifyChange(null, null, this, "messages");
                return;
            }
        }
    }

    /**
     * Reply to a message
     */
    @Command
    public void replymessage() {
        if (Utility.isEmptyString(replymsg)) {
            Clients.evalJavaScript("showNotice('', 'Bạn chưa nhập nội dung trả lời')");
            return;
        }

        if (current == null) {
            Clients.evalJavaScript("showNotice('', '')");
            return;
        }

        MessageService srv = Repository.getInstance().getMessageService();
        srv.replyMessage(current, StringFns.eatQuot(replymsg));

        replymsg = "";

        BindUtils.postNotifyChange(null, null, this, "messages");
        BindUtils.postNotifyChange(null, null, this, "current");
        BindUtils.postNotifyChange(null, null, this, "replymsg");
    }

    /**
     * Load message list from database
     */
    private void loadMessageList() {
        MessageService srv = Repository.getInstance().getMessageService();
        messages = srv.getMessageOfUser(user.getId());
    }

    /**
     * Count unread message
     */
    private void countUnreadMessage() {
        MessageService srv = Repository.getInstance().getMessageService();
        unread = srv.countUnreadMessage(user.getId());
    }

    public List<Message> getMessages() {
        return messages;
    }

    public void setMessages(List<Message> messages) {
        this.messages = messages;
    }

    public Message getCurrent() {
        return current;
    }

    public void setCurrent(Message current) {
        this.current = current;
    }

    public String getToUser() {
        return toUser;
    }

    public void setToUser(String toUser) {
        this.toUser = toUser;
    }

    /**
     * Return string of username of friends of current user
     * @return
     */
    public String getFriends() {
        UserService srv = Repository.getInstance().getUserService();
        List<String> usernames = new ArrayList<String>();
        for (User user : srv.getFriendList(this.user)) {
            usernames.add('"' + user.getUsername() + '"');
        }
        return StringFns.join(usernames.toArray(), ",");
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getNewmsg() {
        return newmsg;
    }

    public void setNewmsg(String newmsg) {
        this.newmsg = newmsg;
    }

    public String getReplymsg() {
        return replymsg;
    }

    public void setReplymsg(String replymsg) {
        this.replymsg = replymsg;
    }

    public long getUnread() {
        return unread;
    }

    public void setUnread(long unread) {
        this.unread = unread;
    }
}
